package com.newegg.hackathon.test;

import com.newegg.hackathon.arangodb.model.Brand;
import com.newegg.hackathon.arangodb.model.Category;
import com.newegg.hackathon.arangodb.model.Item;
import com.newegg.hackathon.arangodb.model.Spec;
import com.newegg.hackathon.model.Edge;
import com.newegg.hackathon.model.Graph;
import com.newegg.hackathon.model.Node;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.arangodb.springframework.core.template.ArangoTemplate;
import com.newegg.hackathon.AppMain;
import com.newegg.hackathon.arangodb.dao.ItemDao;
import com.newegg.hackathon.util.JsonUtil;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes=AppMain.class)
public class ArangoGraphDemo {

	@Autowired
	ArangoTemplate template;
	
	@Autowired
	ItemDao itemDao;
	
	@Test
	public void test() throws Exception{
		Item item = itemDao.getOne();
		CompletableFuture<List<Item>> categoryNear = CompletableFuture.supplyAsync((Supplier<List<Item>>) ()->{
			return itemDao.findCategoryNear(item.getId(), item.getCategory_id(), 10);
    	});
    	CompletableFuture<List<Item>> brandNear = CompletableFuture.supplyAsync((Supplier<List<Item>>) ()->{
			return itemDao.findBrandNear(item.getId(), item.getBrand_id(), 10);
    	});
    	CompletableFuture<List<Item>> nocategoryNear = CompletableFuture.supplyAsync((Supplier<List<Item>>) ()->{
			return itemDao.findNoCategoryNear(item.getId(), item.getCategory_id(), 10);
    	});
    	CompletableFuture<List<Item>> nobrandNear = CompletableFuture.supplyAsync((Supplier<List<Item>>) ()->{
			return itemDao.findNoBrandNear(item.getId(), item.getBrand_id(), 10);
    	});
    	
		Graph graph = new Graph();
		graph.addNode(new Node(item, "main").setSize(100));
		
		Category category = item.getCategory();
		graph.addNode(new Node(category).setSize(70));
		graph.addEdge(new Edge(item.getArangoId(), category.getArangoId()));
		
		Brand brand = item.getBrand();
		graph.addNode(new Node(brand).setSize(70));
		graph.addEdge(new Edge(item.getArangoId(), brand.getArangoId()));
		
		Category nocategory = item.getCategory();
		graph.addNode(new Node("nocategory", "no" + nocategory.getArangoId(), "no" + nocategory.getId(), "Not in " + nocategory.getLabel()).setSize(70));
		graph.addEdge(new Edge(item.getArangoId(), "no" + nocategory.getArangoId()));
		
		Brand nobrand = item.getBrand();
		graph.addNode(new Node("nobrand", "no" + nobrand.getArangoId(), "no" + nobrand.getId(), "Not in " + nobrand.getLabel()).setSize(70));
		graph.addEdge(new Edge(item.getArangoId(), "no" + nobrand.getArangoId()));
		
		for (Spec spec : item.getSpecs()) {
			graph.addNode(new Node(spec).setSize(30));
			graph.addEdge(new Edge(item.getArangoId(), spec.getArangoId(), spec.getProp()));
		}
		for (Item targetItem : categoryNear.get()) {
			graph.addNode(new Node(targetItem, "category").setSize(50));
			graph.addEdge(new Edge(targetItem.getArangoId(), category.getArangoId()));
		}
		for (Item targetItem : brandNear.get()) {
			graph.addNode(new Node(targetItem, "brand").setSize(50));
			graph.addEdge(new Edge(targetItem.getArangoId(), brand.getArangoId()));
		}
		for (Item targetItem : nocategoryNear.get()) {
			graph.addNode(new Node(targetItem, "nocategory").setSize(50));
			graph.addEdge(new Edge(targetItem.getArangoId(), "no" + nocategory.getArangoId()));
		}
		for (Item targetItem : nobrandNear.get()) {
			graph.addNode(new Node(targetItem, "nobrand").setSize(50));
			graph.addEdge(new Edge(targetItem.getArangoId(), "no" + nobrand.getArangoId()));
		}
		System.out.println(JsonUtil.toJsonString(graph));
	}
}
